package com.cms.util;



import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.cms.entity.Article;

public class Lucene {

	private static Statement stmt = null;
	private static ResultSet rs = null;
	
	private static Connection conn = null;
	private static final String URL = "jdbc:mysql://localhost:3306/db_cms?characterEncoding=utf8&useUnicode=true&useSSL=false&serverTimezone=UTC";
	private static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
	private static final String USER_NAME = "root";
	private static final String PASSWORD = "123456";
 
	public static Connection getConnection() {
		try {
			Class.forName(JDBC_DRIVER);
			conn = DriverManager.getConnection(URL, USER_NAME, PASSWORD);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}


    public static ResultSet getResult(String sql, Connection conn) {
        try {
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            return rs;
        } catch (SQLException e) {
            System.out.println(e);
        }
        return null;
    }

 // 索引保存目录
 	private String indexDir = "D:\\lucence\\index";
 	private static IndexSearcher searcher = null;
 	//创建分词器
 	private static Analyzer analyzer = new StandardAnalyzer();


 	/**
	 * 获取数据库数据
	 * @param queryStr 需要检索的关键字
	 * @return
	 * @throws Exception
	 */
	public List<Article> getResult(String queryStr) throws Exception {
		List<Article> result = null;
		conn = Lucene.getConnection();
		if (conn == null) {
			
			throw new Exception("数据库连接失败！");
		}
		String sql = "select * from t_article";
		
		try {
			
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql);
			
			// 给数据库创建索引,此处执行一次，不要每次运行都创建索引
			// 以后数据有更新可以后台调用更新索引
			this.createIndex(rs);
			TopDocs topDocs = this.search(queryStr);
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			result = this.addHits2List(scoreDocs);
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("数据库查询sql出错！ sql : " + sql);
		} finally {
			if (rs != null)
				rs.close();
			if (stmt != null)
				stmt.close();
			if (conn != null)
				conn.close();
		}
		return result;
	}

	/**
	 * 为数据库检索数据创建索引
	 * @param 访问数据库返回的ResultSet
	 * @throws Exception
	 */
	private void createIndex(ResultSet rs) throws Exception {
		// 创建或打开索引
		
		Directory directory = FSDirectory.open(Paths.get(indexDir));
		// 创建IndexWriter
		IndexWriterConfig conf = new IndexWriterConfig(analyzer);
		
		IndexWriter indexWriter = new IndexWriter(directory,conf);
		
		// 遍历ResultSet创建索引
		while (rs.next()) {
			// 创建document并添加field
			Document doc = new Document();			
			doc.add(new TextField("id", rs.getString("id"), Field.Store.YES));
			doc.add(new TextField("title", rs.getString("title"),Field.Store.YES));
			doc.add(new TextField("content", rs.getString("content"),Field.Store.YES));
			doc.add(new TextField("summary", rs.getString("summary"),Field.Store.YES));
			// 将doc添加到索引中			
			indexWriter.addDocument(doc);			
			System.out.println(doc);
		}
		
		indexWriter.commit();
		
		indexWriter.close();
		directory.close();
		
	}


	/**
	 * 检索索引
	 * @param queryStr 需要检索的关键字
	 * @return
	 * @throws Exception
	 */
	private TopDocs search(String queryStr) throws Exception {
		//创建或打开索引目录
		Directory directory = FSDirectory.open(Paths.get(indexDir));
		IndexReader reader = DirectoryReader.open(directory);
		if (searcher == null) {
			searcher = new IndexSearcher(reader);
		}
		//使用查询解析器创建Query
		QueryParser parser = new QueryParser( "title",analyzer);
		Query query = parser.parse(queryStr);
		//从索引中搜索得到排名前10的文档
		TopDocs topDocs = searcher.search(query, 10);
		return topDocs;
	}
 
	/**
	 * 将检索结果添加到List中
	 * @param scoreDocs
	 * @return
	 * @throws Exception
	 */
	private List<Article> addHits2List(ScoreDoc[] scoreDocs) throws Exception {
		List<Article> listBean = new ArrayList<Article>();
		Article bean = null;
		for (int i = 0; i < scoreDocs.length; i++) {
			int docId = scoreDocs[i].doc;
			Document doc = searcher.doc(docId);
			bean = new Article();
			bean.setId(doc.get("id"));
			bean.setTitle(doc.get("title"));
			bean.setContent(doc.get("content"));
			bean.setSummary(doc.get("summary"));
			listBean.add(bean);
		}
		return listBean;
	}
 
	


   

}
